// 导入 MySQL 模块
const mysql = require("mysql");
const util = require("../../common/util");
const config = require("../../common/config");

// 创建 MySQL 连接池
const pool = mysql.createPool(config.dbConfig);

class UserDB {
  /**
   * @constructor
   * @private
   */
  constructor() {
    this.instance = null;
    this.register = this.add;
  }

  /**
   * 创建UserDB对象
   * @returns {UserDB} UserDB实例
   */
  static getInstance() {
    if (!this.instance) {
      this.instance = new UserDB();
    }
    return this.instance;
  }



  /**
   * 获取用户总数
   * @returns {Promise}
   */
  getCount() {
    return new Promise((resolve, reject) => {
      const sql = "SELECT COUNT(1) AS total FROM users";
      pool.query(sql, (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {
          resolve(result[0]);
        }
      });
    });
  }

  /**  
  * 搜索用户  
  * @param {String} q 查询关键字  
  * @param {Number} limit 数量  
  * @param {Number} offset 偏移  
  * @returns {Promise}  
  */
  search(q, limit = -1, offset = -1) {
    // 将 limit 和 offset 转换为数字，如果它们不能转换为数字，则使用默认值  
    limit = Number(limit);
    offset = Number(offset);

    // 如果 limit 或 offset 转换后不是数字，则使用默认值  
    if (isNaN(limit)) {
      limit = -1;
    }
    if (isNaN(offset)) {
      offset = -1;
    }

    // 确保 limit 是一个非负整数  
    limit = Math.max(0, Math.floor(limit));

    return new Promise((resolve, reject) => {
      let sql = "";
      q = `%${q}%`;
      let params = [q, q, q];

      if (limit === -1 || offset === -1) {
        if (limit === -1) {
          // 如果 limit 是默认值，则不添加 LIMIT 子句  
          sql = "SELECT * FROM users WHERE username LIKE ? OR nickname LIKE ? OR truename = ?";
        } else {
          // 如果 offset 是默认值，但 limit 不是，则只添加 LIMIT 子句  
          sql = "SELECT * FROM users WHERE username LIKE ? OR nickname LIKE ? OR truename = ? LIMIT ?";
          params.push(limit);
        }
      } else {
        // 如果 limit 和 offset 都不是默认值，则添加 LIMIT 和 OFFSET 子句  
        sql = "SELECT * FROM users WHERE username LIKE ? OR nickname LIKE ? OR truename = ? LIMIT ? OFFSET ?";
        params.push(limit);
        params.push(offset);
      }

      pool.query(sql, params, (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {
          resolve(result);
        }
      });
    });
  }
  /**
   * 获取指定ID的用户
   * @param {Number} userId 用户ID
   * @returns {Promise}
   */
  find(userId) {
    return new Promise((resolve, reject) => {
      const sql = "SELECT * FROM users WHERE id = ?";
      pool.query(sql, [userId], (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {
          resolve(result[0]);
        }
      });
    });
  }

  /**
   * 获取指定电话号码的用户
   * @param {Number} phoneNumber 用户ID
   * @returns {Promise}
   */
  findByPhone(phoneNumber) {
    return new Promise((resolve, reject) => {
      const sql = "SELECT * FROM users WHERE phone_number = ?";
      pool.query(sql, [phoneNumber], (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {
          resolve(result[0]);
        }
      });
    });
  }
  /**  
  * 获取用户列表  
  * @param {Number} limit 数量  
  * @param {Number} offset 开始  
  * @returns {Promise}  
  */
  findAll(limit = -1, offset = -1) {
    // 将 limit 和 offset 转换为数字  
    limit = Number(limit);
    offset = Number(offset);

    // 检查 limit 和 offset 是否是有效的数字  
    if (isNaN(limit) || isNaN(offset)) {
      // 如果不是有效的数字，可以抛出一个错误或者返回默认值  
      // 这里为了简单起见，我们返回默认值  
      limit = -1;
      offset = -1;
    }

    return new Promise((resolve, reject) => {
      let sql = "";
      let params = [];

      if (limit === -1 && offset === -1) {
        sql = "SELECT * FROM users ORDER BY id";
      } else if (offset === -1) {
        sql = "SELECT * FROM users ORDER BY id LIMIT ?";
        params.push(limit);
      } else {
        sql = "SELECT * FROM users ORDER BY id LIMIT ? OFFSET ?";
        params.push(limit);
        params.push(offset);
      }

      pool.query(sql, params, (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {
          resolve(result);
        }
      });
    });
  }

  /**
   * 新增用户
   * @param {Object} user 用户数据
   * @returns {Promise}
   */
  add(user) {
    return new Promise((resolve, reject) => {
      const sql = `INSERT INTO users(
        username, password, nickname,
        truename, avatar,role, 
        last_login_time, last_login_ip,    
        created_ip, email,
        phone_number
      ) VALUES(
        ?, ?, ?, ?, ?, 
        ?, ?, ?, ?, ?,
        ?
      )`;

      const params = [
        user.username,
        user.password,
        user.nickname,
        user.truename,
        user.avatar,
        user.role,
        user.lastLoginTime,
        user.lastLoginIp,
        user.createdIp,
        user.email,
        user.phoneNumber
      ];

      pool.query(sql, params, (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {   
          resolve(result.insertId); // 插入的数据的自增ID
        }
      });   
    });
  }
  /**  
 * 修改用户  
 * @param {Object} user 用户数据  
 * @returns {Promise}  
 */
  update(user) {
    return new Promise((resolve, reject) => {
      // 构建 SQL 语句和参数列表  
      const sql = `UPDATE users SET  
                  username = ?, password = ?, nickname = ?, truename = ?,  
                  avatar = ?, role = ?, email = ?, phone_number = ?,  
                  is_verified = ?, account_status = ?  
                  WHERE id = ?;`;

      const params = [
        user.username,
        // 在实际应用中，这里应该是密码的哈希值  
        user.password, // 假设你已经在某个地方对密码进行了哈希处理  
        user.nickname,
        user.truename,
        user.avatar,
        user.role,
        user.email,
        user.phoneNumber,
        user.isVerified,
        user.accountStatus,
        user.id // id 应该在 WHERE 子句中作为定位条件，而不是在 SET 子句中  
      ];

      // 如果需要更新密码，并且密码是明文，则应该在这里进行哈希处理  
      // 例如: params[1] = hashFunction(user.password);  

      pool.query(sql, params, (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {
          resolve(result.affectedRows); // 注意这里应该是 affectedRows 而不是 changedRows  
        }
      });
    });
  }

  /**
   * 删除用户
   * @param {Number} userId 用户ID
   * @returns {Promise}
   */
  remove(userId) {
    return new Promise((resolve, reject) => {
      const sql = "DELETE FROM users WHERE id = ?";
      pool.query(sql, [userId], (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {
          resolve(result.affectedRows);
        }
      });
    });
  }

  /**
   * 用户登录
   * @param {String} phone_number
   * @param {String} password 用户密码
   * @returns {Promise}
   */
  login(phoneNumber, password) {
    return new Promise((resolve, reject) => {
      const sql = "SELECT * FROM users WHERE phone_number = ? AND password = ?";
      console.log(password, phoneNumber);
      pool.query(sql, [phoneNumber, password], (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {
          resolve(result[0]);
        }
      });
    });
  }

  /**
   * 用户登录状态
   * @param {String} username 用户名
   * @param {Object} lastLogin 登录状态对象
   * @returns {Promise}
   */
  touch(phone_number, lastLogin) {
    return new Promise((resolve, reject) => {
      // 将时间戳转换为 datetime 格式  
      const lastLoginTime = new Date(lastLogin.time).toISOString().slice(0, 19).replace('T', ' ');

      const sql = `UPDATE users SET   
        last_login_time = ?, last_login_ip = ?,  
        login_count = login_count + 1   
        WHERE phone_number = ?`;

      const params = [lastLoginTime, lastLogin.ip, phone_number];

      pool.query(sql, params, (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {
          resolve(result.changedRows);
        }
      });
    });
  }

  /**
   * 修改用户个人信息
   * @param {Object} id 用户id
   * @param {Object} info 用户信息
   * @returns {Promise}
   */
  changeInfo(id, info) {
    return new Promise((resolve, reject) => {
      const sql = `UPDATE users SET
        nickname = ?, truename = ?, 
        avatar = ?
        WHERE id = ?;`;
      const params = [
        info.nickname,
        info.truename,
        info.avatar,
        id
      ];
      pool.query(sql, params, (err, result) => {
        if (err) {
          util.err(err);
          reject(err);
        } else {
          resolve(result.changedRows);
        }
      });
    });
  }

  /**
   * 修改用户密码
   * @param {Object} user 用户数据
   * @param {String} password 用户密码
   * @returns {Promise}
   */
  changePassword(id, password) {
    return new Promise((resolve, reject) => {
      const sql = `UPDATE users SET
        password = ?
        WHERE id = ?;`;
      const params = [password, id];
      pool.query(sql, params, (err, result) => { if (err) { util.err(err); reject(err); } else { resolve(result.changedRows); } });
    });
  }
}

module.exports = UserDB;